package de.medieninf.sensimg;

import javax.microedition.lcdui.Command;
import javax.microedition.lcdui.CommandListener;
import javax.microedition.lcdui.Display;
import javax.microedition.lcdui.Displayable;
import javax.microedition.midlet.MIDlet;

/**
 * MIDlet to collect and distribute acceleration data and key press information;
 * data is sent as JSON string to central server. Retrieves images from central
 * server and displays them.
 * @author pb
 */
public class SensImgMIDlet extends MIDlet {
    /**
     * The display of the MIDlet.
     */
    private Display display;
    /**
     * The keyboardState of the entire application.
     */
    private KeyboardState keyboardState;
    /**
     * Send UDP packets.
     */
    private UDPSender udpSender;
    /**
     * Command to exit the application.
     */
    private Command cmdExit = new Command("Exit", Command.EXIT, 5);
    /**
     * Command to retrieve images.
     */
    private Command cmdImgRcv = new Command("Image Recv", Command.OK, 4);
    /**
     * Command to check and change the settings.
     */
    private Command cmdSettings = new Command("Settings", Command.OK, 4);
    /**
     * Command to view and use the keypad.
     */
    private Command cmdKeypad = new Command("Keypad", Command.OK, 4);
    /**
     * Command to view the Log.
     */
    private Command cmdLog = new Command("Log", Command.OK, 4);
    /**
     * General command to go back.
     */
    private Command cmdBack = new Command("Back", Command.BACK, 4);
    /**
     * upper CommandListener injected in other screens.
     */
    private CommandListener cl = new CommandListener() {
        public void commandAction(final Command c, final Displayable d) {
            if (c == cmdExit) {
                destroy();
            } else if (c == cmdImgRcv) {
                display.setCurrent(imgRecv);
            } else if (c == cmdSettings) {
                display.setCurrent(settingsForm);
            } else if (c == cmdKeypad) {
                display.setCurrent(keypad);
            } else if (c == cmdLog) {
                logDisplayable.update();
                display.setCurrent(logDisplayable);
            } else {
                display.setCurrent(mainForm);
            }
        }
    };

    /**
     * The MainForm of the application.
     */
    private MainForm mainForm;
    /**
     * The commands of the MainForm.
     */
    private Command[] cmdsMainForm = {cmdExit, cmdImgRcv, cmdSettings,
                                      cmdKeypad, cmdLog};
    /**
     * The settings form.
     */
    private SettingsForm settingsForm;
    /**
     * The commands of the settingsForm.
     */
    private Command[] cmdsSettingsForm = {cmdExit, cmdBack};
    /**
     * The image receiver.
     */
    private ImgRecv imgRecv;
    /**
     * The commands of the image receiver.
     */
    private Command[] cmdsImgRecv = {cmdExit, cmdBack};
    /**
     * The keypad.
     */
    private Keypad keypad;
    /**
     * The commands of the keypad.
     */
    private Command[] cmdsKeypad = {cmdBack};
    /**
     * The display of the logged messages.
     */
    private LogDisplayable logDisplayable;
    /**
     * The commands of the LogDisplayable.
     */
    private Command[] cmdsLogDisplayable = {cmdBack};

    /**
     * Construct the main MIDlet.
     */
    public SensImgMIDlet() {
        keyboardState = new KeyboardState();
        mainForm = new MainForm(cl, cmdsMainForm, keyboardState);
        imgRecv = new ImgRecv(cl, cmdsImgRecv, keyboardState);
        settingsForm = new SettingsForm(cl, cmdsSettingsForm);
        udpSender = new UDPSender(keyboardState);
        udpSender.close(); // avoid read only warning  only
        keypad = new Keypad(cl, cmdsKeypad, keyboardState);
        logDisplayable = new LogDisplayable(cl, cmdsLogDisplayable);
        // Logger.logOnConsole();
    }

    /**
     * starts or restarts the application.
     */
    protected final void startApp() {
        if (display == null) {
            display = Display.getDisplay(this);
        }
        display.setCurrent(mainForm);
    }

    /**
     * Pause the application from within the program.
     */
    public final void pause() {
        pauseApp();
        notifyPaused();
    }

    /**
     * Program should be paused.
     */
    protected final void pauseApp() {
        Settings settings = Settings.getSettings();
        settings.setSensor(false); // stop sensor processing
    }

    /**
     * Destroy the application from within the program.
     */
    public final void destroy() {
        destroyApp(true);
        notifyDestroyed();
    }

    /**
     * Program should be destroyed.
     * @param unconditional may not veto
     */
    protected final void destroyApp(final boolean unconditional) {
        Settings settings = Settings.getSettings();
        settings.setSend(false);
        settings.setBall(false);
        settings.setSensor(false);
    }

}
